package erfgame.frontend.desktop.view.terrain.iso.handler;


import java.awt.Point;
import java.awt.event.MouseEvent;

import erfgame.core.Point3D;
import erfgame.core.world.World;
import erfgame.core.world.terrain.GridRectangle;
import erfgame.core.world.terrain.TerrainUtils;

import erfgame.frontend.desktop.view.terrain.iso.IsometricTerrainView;

public class BaseGridSelectionInteractionHandler extends BaseInteractionHandler {

	private boolean dragging;
	private Point3D startTerrainCoords;
	protected IsometricTerrainView view;
	protected ZLevelSelector zLevelSelector;
	
	public BaseGridSelectionInteractionHandler( 
			IsometricTerrainView view, 
			ZLevelSelector zLevelSelector
	) {
		this.view = view;
		this.zLevelSelector = zLevelSelector;
	}
	
	@Override
	public MouseEvent[] handleMouseEvent(MouseEvent e) {
		MouseEvent[] result;
		switch( e.getID() ) {
		case MouseEvent.MOUSE_PRESSED:
			if( e.getButton() == MouseEvent.BUTTON1 ) {
				this.startTerrainCoords = this.view.getTerrainPosition(e.getX(), e.getY(), new Point3D());
				dragging = true;
				int x = startTerrainCoords.x;
				int y = startTerrainCoords.y;
				int z = startTerrainCoords.z;
				highlight( x, y, z, x, y, z );
				result = null;
			} else {
				result = new MouseEvent[]{e};
			}
			break;
		case MouseEvent.MOUSE_RELEASED:
			if( e.getButton() == MouseEvent.BUTTON1 ) {
				dragging = false;
				Point3D endTerrainCoords = this.view.getTerrainPosition(e.getX(), e.getY(), new Point3D());
				// TODO extrapolate selected tile
				if( startTerrainCoords != null && endTerrainCoords != null ) {
					int sx = this.startTerrainCoords.x;
					int sy = this.startTerrainCoords.y;
					int sz = this.startTerrainCoords.z;
					int ex = endTerrainCoords.x;
					int ey = endTerrainCoords.y;
					int ez = endTerrainCoords.z;
					clearHighlight();
					select( sx, sy, sz, ex, ey, ez );
					view.repaint();
					result = null;
				} else {
					result = new MouseEvent[]{e};
				}
			} else {
				result = new MouseEvent[]{e};
			}
			break;
		case MouseEvent.MOUSE_DRAGGED:
			if( this.dragging ) {
				Point3D endTerrainCoords = this.view.getTerrainPosition(e.getX(), e.getY(), new Point3D());
				int sx = this.startTerrainCoords.x;
				int sy = this.startTerrainCoords.y;
				int sz = this.startTerrainCoords.z;
				if( endTerrainCoords != null ) {
					int ex = endTerrainCoords.x;
					int ey = endTerrainCoords.y;
					int ez = endTerrainCoords.z;
					highlight( sx, sy, sz, ex, ey, ez );
					view.repaint();
				}
				result = null;
			} else {
				result = new MouseEvent[]{e};
			}
			break;
		default:
			result = new MouseEvent[]{e};
		}
		return result;
	}
	
	protected void highlight( int x1, int y1, int z1, int x2, int y2, int z2 ) {
		World world = view.getCurrentWorld();
		Point gridCoordinates1 = world.getGridCoordinates(x1, y1);
		Point gridCoordinates2 = world.getGridCoordinates(x2, y2);
		int gx1 = gridCoordinates1.x;
		int gy1 = gridCoordinates1.y;
		// work out the grid tiles involved
		
		int gx2 = gridCoordinates2.x;
		int gy2 = gridCoordinates2.y;
		
		GridRectangle selectionRectangle = new GridRectangle( gx1, gy1, gx2, gy2 );
		this.zLevelSelector.addZ( z2 );
		highlight( selectionRectangle, zLevelSelector.getRange() );
		
	}

	protected void highlight( GridRectangle selectionRectangle, int[] zRange ) {
		
	}
	
	protected void clearHighlight() {
		this.zLevelSelector.reset();
	}
	
	protected void select( int x1, int y1, int z1, int x2, int y2, int z2 ) {
		World world = view.getCurrentWorld();
		Point gridCoordinates1 = world.getGridCoordinates(x1, y1);
		Point gridCoordinates2 = world.getGridCoordinates(x2, y2);
		int gx1 = gridCoordinates1.x;
		int gy1 = gridCoordinates1.y;
		// work out the grid tiles involved
		
		int gx2 = gridCoordinates2.x;
		int gy2 = gridCoordinates2.y;
		
		GridRectangle selectionRectangle = new GridRectangle( gx1, gy1, gx2, gy2 );
		this.zLevelSelector.addZ( z2 );
		select( selectionRectangle, zLevelSelector.getRange() );
	}
	
	protected void select( GridRectangle selectionRectangle, int[] zRange ) {
		
	}
}
